robobitsfandomcom-20200214-history
Cobot/Start with the code
Writing a Python ROS Node In order to write a python node, you must make a folder in the cobot_python directory. This is because of manifest files that are shared by c++ code but not by python code. You can copy the manifest.xml file from cobot_dialog and change the description to your own name. For the python file, you have some set up to do first. The code snippet is below # setup ROS stuff NODE_NAME = 'cobot_dialog' import roslib; roslib.load_manifest(NODE_NAME) from std_msgs.msg import * import rospy import sys import time from cobot_msgs.srv import * from cobot_msgs.msg import * from sensor_msgs.msg import * class Cobot2Dialog(): def __init__(self): rospy.init_node(NODE_NAME, disable_signals = True) rospy.Subscriber('Cobot/Status', CobotStatusMsg, \ self.__update_status, queue_size=1) rospy.Subscriber('Cobot/TalkerStatus', CobotTalkerMsg, \ self.__update_talker_status, queue_size=1) self.__publish = rospy.Publisher('Cobot/TaskPlannerStatus',CobotTaskPlannerMsg) rospy.Service('Cobot/TPTransport',CobotTPTransportSrv,self.__init_new_transport) *Define a NODE_NAME for your program and add the lines below it. *Make a class of functions for your code, including an __init__ function that subscribes and publishes to different messages and creates services (functions that other Nodes can call). Our example does each - see the Topics and Services page to understand how to use them. *To look up the messages that you should subscribe or publish to, go to the cobot_msgs/msg/ folder and search through the defined messages. To make services, use cobot_msgs/srv *Finally, to run your python node, make sure you have a main method. If you are receiving messages, make sure it runs forever. if __name__ "__main__": Cobot2Dialog() while True: time.sleep(1.0) Writing a C++ ROS Node Source Code New C++ modules should be created in a new folder under cobot_linux/src folder: mkdir myNewModule You first need a main function where the new node is defined. In this main function you can specify the topics that your new node publishes and those that it subscribes. You can find a template with all the necessary includes and initializations at cobot_linux/src/cobot/cobot_node_template.cpp. You just need to copy it into your folder (probably changing the name) cp cobot_linux/src/cobot/cobot_node_template.cpp cobot_linux/src/myNewModule/myModuleMain.cpp and edit it according to your needs. For example, to add a subscription: void myTopicCallBackFunction(type myMessage){ //does whatever you want to do when you receive the topic ... } ... int main(int argc, char **argv) { ... ros::NodeHandle n; ros::Subscriber sub = n.subscribe("myTopic", 1, myTopicCallBackFunction); ... } Compiling To compile your code you need 2 things: first to update the cobot_linux/manifest.xml to include your dependencies. Then to add your new node as a target at the CMakeLists.txt. So, if your node depends on another package from cobot or from ros (e.g. the opencv package), you just need to the line in the cobot_linux/manifest.xml Then you edit the CMakeLists.txt in 2 places (assuming that there is no dependency in external libraries). First add the path for the header files in your node. You will find a list of such entries more or less around line 85 include_directories(${PROJECT_SOURCE_DIR}/src/pathToHeaderFiles) You add one of such lines for each directory you would add in front of a -I in a normal gcc command Second add your node as a target. You will find similar declarations more or less at line 332 set (target yourModule) rosbuild_add_executable(${target} src/myNewModule/myModuleMain.cpp src/myNewModule/OtherCppFile1.cpp src/myNewModule/OtherCppFile2.cpp) add_dependencies(${target} shared_libraries) target_link_libraries(${target} shared_libraries) where the add_dependencies line adds all the packages and libraries that should be compiled before your node and in the target_link_libraries you should add everything that you would put in front of a -L in a normal gcc command. If you have extra libraries you should add their header files using the include_directories and linking them using target_link_libraries. Topics and Services in Python *The rospy.Subscriber function takes a message name and type (from the msg folder), a function to call when the message is received, and the number of these messages to keep in a queue if your code is slower than the message rate. (see the msg folder) *The rospy.Publisher function takes a message name and type. Later, you can publish messages by instantiating a new message of the correct type and including all the arguments self.__publish.publish(CobotTaskPlannerMsg(self.__currentTask,self.__stack0,"",self.__currentFrom, self.__current To, self.__currentObj, False, False, False)) *The rospy.Service function takes a name, service type (from the srv folder), and a function to call when the service is called. To use someone else's service, you must create a ServiceProxy, which returns a function pointer and then call that function with the necessary arguments (defined in the srv file) speaker_call = rospy.ServiceProxy('/Cobot/Talker', CobotTalkerSrv) result = speaker_call(str(words)) Topics and Services in C++ Refer to the ROS C++ Tutorials: http://www.ros.org/wiki/ROS/Tutorials/WritingPublisherSubscriber(c++) http://www.ros.org/wiki/ROS/Tutorials/WritingServiceClient(c++) Running Nodes You will need to start the nodes that your program depends on and then your own program. *If those nodes are found in the cobot_linux directory: In the cobot_linux directory, run ./bin/''nameOfTheNode'' for each of the nodes that you need. For example, ./bin/cobot_manager to get the status of the robot and ./bin/cobot_talker to get the last thing cobot said. *If those nodes are found in the cobot_python directory: In your directory, run python nodename.py